package com.fan.shop.views.bean;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ser.FilterProvider;
import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter;
import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider;

import com.fan.shop.businesslogic.ItemDeleteProcess;
import com.fan.shop.global.JacksonMapper;
import com.fan.shop.global.ShopGlobalVariables;
import com.fan.shop.model.userclass.ItemUserClass;
import com.fan.shop.services.CategoryService;
import com.fan.shop.services.ItemService;
import com.fan.shop.services.LocationService;
import com.fan.shop.services.TransactionReferenceService;
import com.fan.shop.services.UserService;

@ManagedBean(name = "itemsBean")
@RequestScoped
public class ItemsBean extends ShopBean {

	private static Logger logger = Logger.getLogger(ItemsBean.class);

	@ManagedProperty(value = "#{itemService}")
	private ItemService itemService;

	@ManagedProperty(value = "#{categoryService}")
	private CategoryService categoryService;

	@ManagedProperty(value = "#{locationService}")
	private LocationService locationService;

	@ManagedProperty(value = "#{transactionReferenceService}")
	private TransactionReferenceService transactionReferenceService;

	@ManagedProperty(value = "#{userService}")
	private UserService userService;

	private String editItemCode;
	private String editItemName;
	private String editItemDescription;
	private BigDecimal editPrice;
	private String editOrigLocation;
	private String editCategory;
	private String editIcon;
	private String editAttributes;
	private boolean editSuspended;
	private String editBrand;

	private String tableData;
	private int columnsSize;
	private List<String> columnNames;

	private String selectedValue;

	private ShopBean currentBean;

	public static Logger getLogger() {
		return logger;
	}

	public static void setLogger(Logger logger) {
		ItemsBean.logger = logger;
	}

	public ItemService getItemService() {
		return itemService;
	}

	public void setItemService(ItemService itemService) {
		this.itemService = itemService;
	}

	public String getEditItemCode() {
		return editItemCode;
	}

	public void setEditItemCode(String editItemCode) {
		this.editItemCode = editItemCode;
	}

	public String getEditItemName() {
		return editItemName;
	}

	public void setEditItemName(String editItemName) {
		this.editItemName = editItemName;
	}

	public String getEditItemDescription() {
		return editItemDescription;
	}

	public void setEditItemDescription(String editItemDescription) {
		this.editItemDescription = editItemDescription;
	}

	public BigDecimal getEditPrice() {
		return editPrice;
	}

	public void setEditPrice(BigDecimal editPrice) {
		this.editPrice = editPrice;
	}

	public String getEditOrigLocation() {
		return editOrigLocation;
	}

	public void setEditOrigLocation(String editOrigLocation) {
		this.editOrigLocation = editOrigLocation;
	}

	public String getEditCategory() {
		return editCategory;
	}

	public void setEditCategory(String editCategory) {
		this.editCategory = editCategory;
	}

	public String getEditIcon() {
		if (editItemCode != null && editItemCode.trim().length() > 0
				&& itemService != null) {
			editIcon = itemService.getItem(editItemCode).getIcon();
		}
		return editIcon;
	}

	public void setEditIcon(String editIcon) {
		this.editIcon = editIcon;
	}

	public String getEditAttributes() {
		return editAttributes;
	}

	public void setEditAttributes(String editAttributes) {
		this.editAttributes = editAttributes;
	}

	public boolean getEditSuspended() {
		return editSuspended;
	}

	public void setEditSuspended(boolean editSuspended) {
		this.editSuspended = editSuspended;
	}

	public String getEditBrand() {
		return editBrand;
	}

	public void setEditBrand(String editBrand) {
		this.editBrand = editBrand;
	}

	public CategoryService getCategoryService() {
		return categoryService;
	}

	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}

	public LocationService getLocationService() {
		return locationService;
	}

	public void setLocationService(LocationService locationService) {
		this.locationService = locationService;
	}

	public TransactionReferenceService getTransactionReferenceService() {
		return transactionReferenceService;
	}

	public void setTransactionReferenceService(
			TransactionReferenceService transactionReferenceService) {
		this.transactionReferenceService = transactionReferenceService;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public String getTableData() {
		ObjectMapper mapper = JacksonMapper.getInstance();

		Set<String> columnNames = new HashSet<String>();

		for (String name : itemService.getColumnNames()) {

			columnNames.add(name);
		}
		FilterProvider filters = new SimpleFilterProvider().addFilter(
				"myFilter",
				SimpleBeanPropertyFilter.filterOutAllExcept(columnNames));

		tableData = "\"aaData\": [";
		StringBuffer data = new StringBuffer();

		for (Object obj : itemService.getList()) {
			try {

				ItemUserClass itemUserClass = (ItemUserClass) itemService
						.copy(obj);

				String line = mapper.writer(filters).writeValueAsString(
						itemUserClass);
				data = data.append(line);
			} catch (JsonGenerationException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		String tmp = data.toString().replaceAll("\\{[^,:\\{\\}]*:", "[");
		tmp = tmp.replaceAll(",[^,:\\{\\}]*:", ",");

		tableData = tableData + tmp.replace("{", "[").replace("}", "],");
		if (tableData.endsWith(",")) {
			tableData = tableData.substring(0, tableData.length() - 1);
		}

		tableData = tableData + "]";

		return tableData;
	}

	public void setTableData(String tableData) {
		this.tableData = tableData;
	}

	public int getColumnsSize() {
		columnsSize = getColumnNames().size();
		return columnsSize;
	}

	public void setColumnsSize(int columnsSize) {
		this.columnsSize = columnsSize;
	}

	public List<String> getColumnNames() {
		columnNames = itemService.getColumnNames();
		return columnNames;
	}

	public void setColumnNames(List<String> columnNames) {
		this.columnNames = columnNames;
	}

	public String getSelectedValue() {
		return selectedValue;
	}

	public void setSelectedValue(String selectedValue) {
		this.selectedValue = selectedValue;
	}

	public ShopBean getCurrentBean() {
		currentBean = this;
		return currentBean;
	}

	public void setCurrentBean(ShopBean currentBean) {
		this.currentBean = currentBean;
	}

	public String openItemAction() {

		FacesContext.getCurrentInstance().getExternalContext().getRequestMap()
				.put("item_code", editItemCode);
		return "item";
	}

	public String deleteItemAction() {
		ItemDeleteProcess itemDeleteProcess = new ItemDeleteProcess();
		itemDeleteProcess.setItemCode(editItemCode);
		itemDeleteProcess.setItemService(itemService);
		int result = itemDeleteProcess.process();
		if (result == ShopGlobalVariables.FAILED) {
			return "items";
		} else {
			return "items";
		}
	}

	public String createItemAction() {

		return "create_item.faces";
	}

	public String testAction() {

		logger.info(userService.getCurrentUser().getUsername());
		logger.info(userService.isCurrentUserGroupAdmin());
		return "items.faces";
	}

}
